package com.gmadmin.sysadmin.security.service;

import com.gmadmin.gmmbg.dto.PermsDto;
import com.gmadmin.gmmbg.mapper.SysRoleMapper;
import com.gmadmin.sysadmin.security.config.PermsConfig;
import com.gmadmin.sysadmin.security.dto.AuthorityDto;
import com.gmadmin.sysadmin.security.utils.RedisUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
@AllArgsConstructor
public class OnlinePermsService {

    private final RedisUtils redisUtils;
    private final SysRoleMapper sysRoleMapper;
    private final PermsConfig permsConfig;

    /**
     * 保存角色和菜单的关系
     */
    public Map<String, List<PermsDto>> init(){
        List<PermsDto> permsDto = sysRoleMapper.findPermsDto();
        Map<String, List<PermsDto>> parmsMap = permsDto.stream().collect(Collectors.groupingBy(PermsDto::roleCode));
        redisUtils.set(permsConfig.getKey(), parmsMap, permsConfig.getValidityInSeconds(), TimeUnit.MILLISECONDS);
        return parmsMap;
    }

    /**
     * 刷新角色和菜单的关系
     */
    public Map<String, List<PermsDto>> refresh(){
        return init();
    }

    public List<PermsDto> getPermsDto(String roleCode){
        Map<String, List<PermsDto>> permsMap = (Map<String, List<PermsDto>>)redisUtils.get(permsConfig.getKey());
        return permsMap.get(roleCode);
    }

    public List<AuthorityDto> findPermsDto(Set<String> roleCodes){
        Map<String, List<PermsDto>> permsMap = (Map<String, List<PermsDto>>)redisUtils.get(permsConfig.getKey());
        if(permsMap == null || permsMap.isEmpty()){
            permsMap = refresh();  //取不到就刷新一下
        }
        List<PermsDto> permsDtosResult = new ArrayList<>();
        Map<String, List<PermsDto>> finalPermsMap = permsMap;
        roleCodes.forEach(roleCode -> {
            permsDtosResult.addAll(finalPermsMap.get(roleCode));
        });
        return permsDtosResult.stream().filter(Objects::nonNull).map(PermsDto::path).map(AuthorityDto::new).toList();
    }

}
